package com.youbug.mall.order_oms.service.impl;

import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youbug.common.constant.AuthServerConstant;
import com.youbug.common.exception.NoStockException;
import com.youbug.common.to.mq.SeckillOrderTo;
import com.youbug.mall.cart.interceptor.CartInterceptor;
import com.youbug.mall.order_oms.interceptor.OrderInterceptor;
import com.youbug.common.to.OrderTo;
import com.youbug.common.to.SkuHasStockTo;
import com.youbug.common.to.UmsMemberTo;
import com.youbug.common.to.UserInfoTo;
import com.youbug.common.vo.*;
import com.youbug.mall.order_oms.constant.PayConstant;
import com.youbug.mall.order_oms.entity.OmsOrder;
import com.youbug.mall.order_oms.entity.OmsOrderItem;
import com.youbug.mall.order_oms.entity.OmsPaymentInfo;
import com.youbug.mall.order_oms.enume.OrderStatusEnum;
import com.youbug.mall.order_oms.feign.IOrderCartFeignService;
import com.youbug.mall.order_oms.feign.IOrderMemberFeignService;
import com.youbug.mall.order_oms.feign.IOrderProductFeignService;
import com.youbug.mall.order_oms.feign.IOrderWareFeignService;
import com.youbug.mall.order_oms.mapper.OmsOrderMapper;
import com.youbug.mall.order_oms.service.IOmsOrderItemService;
import com.youbug.mall.order_oms.service.IOmsOrderService;
import com.youbug.mall.order_oms.service.IOmsPaymentInfoService;
import com.youbug.mall.order_oms.to.OrderCreateTo;
import com.youbug.mall.order_oms.vo.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.youbug.mall.order_oms.constant.OrderConstant.USER_ORDER_TOKEN_PREFIX;

@Service
public class OmsOrderServiceImpl extends ServiceImpl<OmsOrderMapper, OmsOrder> implements IOmsOrderService {

    private ThreadLocal<OrderSubmitVo> confirmVoThreadLocal = new ThreadLocal<>();

    @Autowired
    private IOmsOrderItemService orderItemService;

    @Autowired
    private IOrderMemberFeignService orderMemberFeignService;

    @Autowired
    private IOrderProductFeignService orderProductFeignService;

    @Autowired
    private IOrderCartFeignService orderCartFeignService;

    @Autowired
    private IOrderWareFeignService wareFeignService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private ThreadPoolExecutor executor;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private IOmsPaymentInfoService paymentInfoService;

    @Autowired
    private HttpServletRequest request;

    @Override
    public IPage<OmsOrder> getOmsOrderPage(QueryVo<OmsOrder> queryVo) {

        Page<OmsOrder> paramPage = new Page<>();

        paramPage.setCurrent(queryVo.getCurrentPage());

        paramPage.setSize(queryVo.getPageSize());

        QueryWrapper<OmsOrder> wrapper = new QueryWrapper<>();

        OmsOrder omsOrder = queryVo.getPayload();

        if(!ObjectUtils.isEmpty(omsOrder)){
            if(omsOrder.getId()!=null){
                wrapper.gt("id", omsOrder.getId());
            }
            if(omsOrder.getMemberId()!=null){
                wrapper.eq("member_id", omsOrder.getMemberId());
            }
            if(StringUtils.hasText(omsOrder.getOrderSn())){
                wrapper.eq("order_sn", omsOrder.getOrderSn());
            }
            if(omsOrder.getCouponId()!=null){
                wrapper.eq("coupon_id", omsOrder.getCouponId());
            }
            if(StringUtils.hasText(omsOrder.getMemberUsername())){
                wrapper.eq("member_username", omsOrder.getMemberUsername());
            }
            if(omsOrder.getPayType()!=null){
                wrapper.eq("pay_type", omsOrder.getPayType());
            }
            if(omsOrder.getSourceType()!=null){
                wrapper.eq("source_type", omsOrder.getSourceType());
            }
            if(omsOrder.getStatus()!=null){
                wrapper.eq("status", omsOrder.getStatus());
            }
            if(StringUtils.hasText(omsOrder.getDeliveryCompany())){
                wrapper.eq("delivery_company", omsOrder.getDeliveryCompany());
            }
            if(StringUtils.hasText(omsOrder.getDeliverySn())){
                wrapper.eq("delivery_sn", omsOrder.getDeliverySn());
            }
            if(omsOrder.getAutoConfirmDay()!=null){
                wrapper.eq("auto_confirm_day", omsOrder.getAutoConfirmDay());
            }
            if(omsOrder.getIntegration()!=null){
                wrapper.eq("integration", omsOrder.getIntegration());
            }
            if(omsOrder.getGrowth()!=null){
                wrapper.eq("growth", omsOrder.getGrowth());
            }
            if(omsOrder.getBillType()!=null){
                wrapper.eq("bill_type", omsOrder.getBillType());
            }
            if(StringUtils.hasText(omsOrder.getBillHeader())){
                wrapper.eq("bill_header", omsOrder.getBillHeader());
            }
            if(StringUtils.hasText(omsOrder.getBillContent())){
                wrapper.eq("bill_content", omsOrder.getBillContent());
            }
            if(StringUtils.hasText(omsOrder.getBillReceiverPhone())){
                wrapper.eq("bill_receiver_phone", omsOrder.getBillReceiverPhone());
            }
            if(StringUtils.hasText(omsOrder.getBillReceiverEmail())){
                wrapper.eq("bill_receiver_email", omsOrder.getBillReceiverEmail());
            }
            if(StringUtils.hasText(omsOrder.getReceiverName())){
                wrapper.eq("receiver_name", omsOrder.getReceiverName());
            }
            if(StringUtils.hasText(omsOrder.getReceiverPhone())){
                wrapper.eq("receiver_phone", omsOrder.getReceiverPhone());
            }
            if(StringUtils.hasText(omsOrder.getReceiverPostCode())){
                wrapper.eq("receiver_post_code", omsOrder.getReceiverPostCode());
            }
            if(StringUtils.hasText(omsOrder.getReceiverProvince())){
                wrapper.eq("receiver_province", omsOrder.getReceiverProvince());
            }
            if(StringUtils.hasText(omsOrder.getReceiverCity())){
                wrapper.eq("receiver_city", omsOrder.getReceiverCity());
            }
            if(StringUtils.hasText(omsOrder.getReceiverRegion())){
                wrapper.eq("receiver_region", omsOrder.getReceiverRegion());
            }
            if(StringUtils.hasText(omsOrder.getReceiverDetailAddress())){
                wrapper.eq("receiver_detail_address", omsOrder.getReceiverDetailAddress());
            }
            if(StringUtils.hasText(omsOrder.getNote())){
                wrapper.eq("note", omsOrder.getNote());
            }
            if(omsOrder.getConfirmStatus()!=null){
                wrapper.eq("confirm_status", omsOrder.getConfirmStatus());
            }
            if(omsOrder.getDeleteStatus()!=null){
                wrapper.eq("delete_status", omsOrder.getDeleteStatus());
            }
            if(omsOrder.getUseIntegration()!=null){
                wrapper.eq("use_integration", omsOrder.getUseIntegration());
            }
            if(!ObjectUtils.isEmpty(omsOrder.getPaymentTime())){
                wrapper.eq("payment_time", omsOrder.getPaymentTime());
            }
            if(!ObjectUtils.isEmpty(omsOrder.getDeliveryTime())){
                wrapper.eq("delivery_time", omsOrder.getDeliveryTime());
            }
            if(!ObjectUtils.isEmpty(omsOrder.getReceiveTime())){
                wrapper.eq("receive_time", omsOrder.getReceiveTime());
            }
            if(!ObjectUtils.isEmpty(omsOrder.getCommentTime())){
                wrapper.eq("comment_time", omsOrder.getCommentTime());
            }
            if(!ObjectUtils.isEmpty(omsOrder.getModifyTime())){
                wrapper.eq("modify_time", omsOrder.getModifyTime());
            }
        }
        if(!ObjectUtils.isEmpty(queryVo.getStartTime())){
            wrapper.gt("create_time", queryVo.getStartTime());
        }
        if(!ObjectUtils.isEmpty(queryVo.getEndTime())){
            wrapper.lt("create_time", queryVo.getEndTime());
        }
        wrapper.orderByDesc("create_time");

        Page<OmsOrder> page = this.page(paramPage, wrapper);

        return page;
    }

       /* @Transactional(transactionManager = "transactionManagerXXX", rollbackFor = Exception.class)
        public boolean saveBatch(Collection<OmsOrder> entityList) {
        return saveBatch(entityList, DEFAULT_BATCH_SIZE);
        }
        */
    @Override
    public IPage<OmsOrder> getOmsOrderPageWithItem(QueryVo<OmsOrder> queryVo){
        IPage<OmsOrder> orderPage = this.getOmsOrderPage(queryVo);

        List<OmsOrder> orders = orderPage.getRecords();

        List<String> orderSns = orders.stream().map(OmsOrder::getOrderSn).collect(Collectors.toList());

        List<OmsOrderItem> items = orderItemService.list(new QueryWrapper<OmsOrderItem>().in("order_sn", orderSns));

        Map<String, List<OmsOrderItem>> listMap = items.stream().collect(Collectors.groupingBy(OmsOrderItem::getOrderSn));

        orders.forEach(o->{
            o.setOrderItemListTemp(listMap.get(o.getOrderSn()));
        });

        return orderPage;
    }

    @Override
    public String handlePayResult(PayAsyncVo asyncVo) {
        //保存交易流水信息
        OmsPaymentInfo paymentInfo = new OmsPaymentInfo();
        paymentInfo.setOrderSn(asyncVo.getOut_trade_no());
        paymentInfo.setAlipayTradeNo(asyncVo.getTrade_no());
        paymentInfo.setTotalAmount(new BigDecimal(asyncVo.getBuyer_pay_amount()));
        paymentInfo.setSubject(asyncVo.getBody());
        paymentInfo.setPaymentStatus(asyncVo.getTrade_status());
        paymentInfo.setCreateTime(new Date());

        paymentInfo.setCallbackTime(LocalDateTime.parse(asyncVo.getNotify_time(),
                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")).atZone(ZoneId.of("UTC+8")).toLocalDateTime());

        paymentInfo.setCallbackContent(asyncVo.toString());
        //添加到数据库中
        paymentInfoService.save(paymentInfo);
        //修改订单状态
        //获取当前状态
        String tradeStatus = asyncVo.getTrade_status();

        if (tradeStatus.equals("TRADE_SUCCESS") || tradeStatus.equals("TRADE_FINISHED")) {
            //支付成功状态
            String orderSn = asyncVo.getOut_trade_no(); //获取订单号

            OmsOrder omsOrder = new OmsOrder();

            omsOrder.setStatus(OrderStatusEnum.PAYED.getCode());
            omsOrder.setPayType(PayConstant.ALIPAY);
            omsOrder.setPaymentTime(LocalDateTime.now());

            update(omsOrder, new QueryWrapper<OmsOrder>().eq("order_sn", orderSn));
        }

        return "success";
    }

    @Override
    public OrderConfirmVo confirmOrder() throws ExecutionException, InterruptedException {

        UmsMemberTo memberTo = OrderInterceptor.loginUser.get();

        OrderConfirmVo confirmVo = new OrderConfirmVo();

        CompletableFuture<Void> addressAsync = CompletableFuture.runAsync(() -> {

            List<MemberAddressVo> addressList = orderMemberFeignService.getAddress(memberTo.getId());// 地址列表

            confirmVo.setMemberAddressVos(addressList);

        }, executor);

        UserInfoTo userInfoTo = CartInterceptor.toThreadLocal.get();

        CompletableFuture<Void> itemAsync = CompletableFuture.runAsync(() -> {

            CartInterceptor.toThreadLocal.set(userInfoTo);

            List<OrderItemVo> orderItemVos = orderCartFeignService.getCurrentUserCartItems();// 购物项

            confirmVo.setItems(orderItemVos);

        }, executor).thenRunAsync(()->{
            List<OrderItemVo> items = confirmVo.getItems();
            List<Long> skuIds = items.stream().map(e -> {
                return e.getSkuId();

            }).collect(Collectors.toList());

            //远程查询商品库存信息
            List<SkuHasStockTo>  skuHasStocks = wareFeignService.getSkuHasStock(skuIds);

            if (skuHasStocks != null && skuHasStocks.size() > 0) {
                //将skuStockVos集合转换为map
                Map<Long, Boolean> skuHasStockMap = skuHasStocks.stream().collect(Collectors.toMap(SkuHasStockTo::getSkuId, SkuHasStockTo::getHasStock));
                confirmVo.setStocks(skuHasStockMap);
            }

        },executor);
        CompletableFuture.allOf(addressAsync,itemAsync).get();

        Integer integration = memberTo.getIntegration();// 积分

        confirmVo.setIntegration(integration);

        //5、防重令牌(防止表单重复提交)
        //为用户设置一个token，三十分钟过期时间（存在redis）
        String token = UUID.randomUUID().toString().replace("-", "");
        redisTemplate.opsForValue().set(USER_ORDER_TOKEN_PREFIX + memberTo.getId(), token,30, TimeUnit.MINUTES);
        confirmVo.setOrderToken(token);

        return confirmVo;
    }

    @Override
//    @GlobalTransactional
    @Transactional(transactionManager = "transactionManagerOms", rollbackFor = Exception.class)
    public SubmitOrderResponseVo submitOrder(OrderSubmitVo vo) {
        confirmVoThreadLocal.set(vo);

        SubmitOrderResponseVo responseVo = new SubmitOrderResponseVo();
        //去创建、下订单、验令牌、验价格、锁定库存...

        //获取当前用户登录的信息
        UmsMemberTo memberTo = OrderInterceptor.loginUser.get();
        responseVo.setCode(0);

        //1、验证令牌是否合法【令牌的对比和删除必须保证原子性】
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        String orderToken = vo.getOrderToken();

        //通过lure脚本原子验证令牌和删除令牌
        Long result = redisTemplate.execute(new DefaultRedisScript<>(script, Long.class),
                Arrays.asList(USER_ORDER_TOKEN_PREFIX + memberTo.getId()), orderToken);

        if (result == 0L) {
            //令牌验证失败
            responseVo.setCode(1);
            return responseVo;
        } else {
            //令牌验证成功
            //1、创建订单、订单项等信息
            OrderCreateTo orderCreateTo = createOrder();
            //2、验证价格
            BigDecimal payAmount = orderCreateTo.getOrder().getPayAmount();
            BigDecimal payPrice = vo.getPayPrice();

            if (Math.abs(payAmount.subtract(payPrice).doubleValue()) < 0.01) {
                //金额对比
                //TODO 3、保存订单
                saveOrder(orderCreateTo);

                //4、库存锁定,只要有异常，回滚订单数据
                //订单号、所有订单项信息(skuId,skuNum,skuName)
                WareSkuLockVo lockVo = new WareSkuLockVo();
                lockVo.setOrderSn(orderCreateTo.getOrder().getOrderSn());

                //获取出要锁定的商品数据信息
                List<OrderItemVo> orderItemVos = orderCreateTo.getOrderItems().stream().map((item) -> {
                    OrderItemVo orderItemVo = new OrderItemVo();
                    orderItemVo.setSkuId(item.getSkuId());
                    orderItemVo.setCount(item.getSkuQuantity());
                    orderItemVo.setTitle(item.getSkuName());
                    return orderItemVo;
                }).collect(Collectors.toList());
                lockVo.setLocks(orderItemVos);

                //TODO 调用远程锁定库存的方法
                //出现的问题：扣减库存成功了，但是由于网络原因超时，出现异常，导致订单事务回滚，库存事务不回滚(解决方案：seata)
                //为了保证高并发，不推荐使用seata，因为是加锁，并行化，提升不了效率,可以发消息给库存服务
                R<Boolean> r = wareFeignService.orderLockStock(lockVo);
                if (r.getCode() == R.SUCCESS) {
                    //锁定成功
                    responseVo.setOrder(orderCreateTo.getOrder());

                    //删除购物车里的数据
//                    redisTemplate.delete(CartConstant.CART_PREFIX + memberTo.getId());
                    // 创建订单成功，发送给MQ
                   rabbitTemplate.convertAndSend("order.event.exchange",
                           "order.create.order", orderCreateTo.getOrder());
                    return responseVo;
                } else {
                    //锁定失败
                    throw new NoStockException(r.getMsg());
                    // responseVo.setCode(3);
                    // return responseVo;
                }
            } else {
                responseVo.setCode(2);
                return responseVo;
            }
        }
    }

    @Override
    public void closeOrder(OmsOrder order) {

        OmsOrder omsOrder = this.getById(order.getId());

        if(OrderStatusEnum.CREATE_NEW.getCode().equals(omsOrder.getStatus())){
            // 关单
            OmsOrder temp = new OmsOrder();
            temp.setId(order.getId());
            temp.setStatus(OrderStatusEnum.CANCLED.getCode());
            this.updateById(temp);
            OrderTo orderTo = new OrderTo();
            BeanUtils.copyProperties(omsOrder, orderTo);
            try {
                // 给mq发消息解锁库存
                // 每一条消息做好日志记录
                rabbitTemplate.convertAndSend("order-event-exchange","order.ralease.other", orderTo);
            }catch (Exception e){
                // 将没发送成功的消息保存到数据库 ，定期扫描数据库，重新发送
            }
        }
    }

    @Override
    public PayVo getOrderPay(String orderSn) {

        PayVo payVo = new PayVo();
        OmsOrder orderInfo = this.getOrderByOrderSn(orderSn);

        //保留两位小数点，向上取值
        BigDecimal payAmount = orderInfo.getPayAmount().setScale(2, BigDecimal.ROUND_UP);
        payVo.setTotal_amount(payAmount.toString());
        payVo.setOut_trade_no(orderInfo.getOrderSn());

        //查询订单项的数据
        List<OmsOrderItem> orderItemInfo = orderItemService.list(
                new QueryWrapper<OmsOrderItem>().eq("order_sn", orderSn));
        OmsOrderItem orderItem = orderItemInfo.get(0);
        payVo.setBody(orderItem.getSkuAttrsVals());

        payVo.setSubject(orderItem.getSkuName());

        return payVo;
    }

    @Override
    public OmsOrder getOrderByOrderSn(String orderSn) {
        OmsOrder omsOrder = this.getOne(new QueryWrapper<OmsOrder>().eq("order_sn", orderSn));

        return omsOrder;
    }

    private void saveOrder(OrderCreateTo orderCreateTo) {
        try {
            //获取订单信息
            OmsOrder order = orderCreateTo.getOrder();
            order.setModifyTime(LocalDateTime.now());
            order.setCreateTime(new Date());
            //保存订单
            save(order);
            //获取订单项信息
            List<OmsOrderItem> orderItems = orderCreateTo.getOrderItems();
            //批量保存订单项数据
            orderItemService.saveBatch(orderItems);
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException();
        }
    }

    private OrderCreateTo createOrder() {

        OrderCreateTo createTo = new OrderCreateTo();
        //1、生成订单号
        String orderSn = IdWorker.getIdStr();
        OmsOrder order = builderOrder(orderSn);

        //2、获取到所有的订单项
        List<OmsOrderItem> orderItems = builderOrderItems(orderSn);

        //3、验价(计算价格、积分等信息)
        computePrice(order, orderItems);

        createTo.setOrder(order);
        createTo.setOrderItems(orderItems);

        return createTo;
    }

    private OmsOrder builderOrder(String orderSn) {

        //获取当前用户登录信息
        UmsMemberTo memberTo = OrderInterceptor.loginUser.get();

        OmsOrder order = new OmsOrder();
        order.setMemberId(memberTo.getId());
        order.setOrderSn(orderSn);
        order.setMemberUsername(memberTo.getUsername());

        OrderSubmitVo orderSubmitVo = confirmVoThreadLocal.get();

        //远程获取收货地址和运费信息
        FareVo fareVo = wareFeignService.getFare(orderSubmitVo.getAddrId());
        //获取到运费信息
        BigDecimal fare = fareVo.getFare();
        order.setFreightAmount(fare);

        //获取到收货地址信息
        MemberAddressVo address = fareVo.getAddress();
        //设置收货人信息
        order.setReceiverName(address.getName());
        order.setReceiverPhone(address.getPhone());
        order.setReceiverPostCode(address.getPostCode());
        order.setReceiverProvince(address.getProvince());
        order.setReceiverCity(address.getCity());
        order.setReceiverRegion(address.getRegion());
        order.setReceiverDetailAddress(address.getDetailAddress());

        //设置订单相关的状态信息
        order.setStatus(OrderStatusEnum.CREATE_NEW.getCode());
        order.setAutoConfirmDay(7);
        order.setConfirmStatus(0);
        return order;
    }

    public List<OmsOrderItem> builderOrderItems(String orderSn) {

        List<OmsOrderItem> omsOrderItems = new ArrayList<>();

        //最后确定每个购物项的价格
        List<OrderItemVo> currentCartItems = orderCartFeignService.getCurrentUserCartItems();
        if (currentCartItems != null && currentCartItems.size() > 0) {
            omsOrderItems = currentCartItems.stream().map((items) -> {
                //构建订单项数据
                OmsOrderItem orderItem = builderOrderItem(items);
                orderItem.setOrderSn(orderSn);

                return orderItem;
            }).collect(Collectors.toList());
        }

        return omsOrderItems;
    }

    private OmsOrderItem builderOrderItem(OrderItemVo items) {

        OmsOrderItem orderItem = new OmsOrderItem();

        //1、商品的spu信息
        Long skuId = items.getSkuId();
        //获取spu的信息
        SpuInfoVo spuInfo = orderProductFeignService.getSpuInfoBySkuId(skuId);

        orderItem.setSpuId(spuInfo.getId());
        orderItem.setSpuName(spuInfo.getSpuName());
        orderItem.setSpuBrand(spuInfo.getBrandName());
        orderItem.setCategoryId(spuInfo.getCatalogId());

        //2、商品的sku信息
        orderItem.setSkuId(skuId);
        orderItem.setSkuName(items.getTitle());
        orderItem.setSkuPic(items.getImage());
        orderItem.setSkuPrice(items.getPrice());
        orderItem.setSkuQuantity(items.getCount());

        //使用StringUtils.collectionToDelimitedString将list集合转换为String
        String skuAttrValues = StringUtils.collectionToDelimitedString(items.getSkuAttrValues(), ";");
        orderItem.setSkuAttrsVals(skuAttrValues);

        //3、商品的优惠信息

        //4、商品的积分信息
        orderItem.setGiftIntegration(items.getPrice().multiply(new BigDecimal(items.getCount())).intValue());
        orderItem.setGiftGrowth(items.getPrice().multiply(new BigDecimal(items.getCount())).intValue());// 成长值

        //5、订单项的价格信息
        orderItem.setPromotionAmount(BigDecimal.ZERO);// 促销减除价格
        orderItem.setCouponAmount(BigDecimal.ZERO);// 优惠券
        orderItem.setIntegrationAmount(BigDecimal.ZERO);// 积分优惠价

        //当前订单项的实际金额.总额 - 各种优惠价格
        //原来的价格
        BigDecimal origin = orderItem.getSkuPrice().multiply(new BigDecimal(orderItem.getSkuQuantity().toString()));
        //原价减去优惠价得到最终的价格
        BigDecimal subtract = origin.subtract(orderItem.getCouponAmount())
                .subtract(orderItem.getPromotionAmount())
                .subtract(orderItem.getIntegrationAmount());
        orderItem.setRealAmount(subtract);

        return orderItem;
    }

    private void computePrice(OmsOrder order, List<OmsOrderItem> orderItems) {

        //总价
        BigDecimal total = new BigDecimal("0.0");
        //优惠价
        BigDecimal coupon = new BigDecimal("0.0");
        BigDecimal intergration = new BigDecimal("0.0");
        BigDecimal promotion = new BigDecimal("0.0");

        //积分、成长值
        Integer integrationTotal = 0;
        Integer growthTotal = 0;

        //订单总额，叠加每一个订单项的总额信息
        for (OmsOrderItem orderItem : orderItems) {
            //优惠价格信息
            coupon = coupon.add(orderItem.getCouponAmount());
            promotion = promotion.add(orderItem.getPromotionAmount());
            intergration = intergration.add(orderItem.getIntegrationAmount());

            //总价
            total = total.add(orderItem.getRealAmount());

            //积分信息
            integrationTotal += orderItem.getGiftIntegration();
            growthTotal += orderItem.getGiftGrowth();//成长值信息

        }
        //1、订单价格相关的
        order.setTotalAmount(total);
        //设置应付总额(总额+运费)
        order.setPayAmount(total.add(order.getFreightAmount()));
        order.setCouponAmount(coupon);
        order.setPromotionAmount(promotion);// 促销
        order.setIntegrationAmount(intergration);

        //设置积分成长值信息
        order.setIntegration(integrationTotal);
        order.setGrowth(growthTotal);

        //设置删除状态(0-未删除，1-已删除)
        order.setDeleteStatus(0);
    }

    @Override
    public void createSeckillOrder(SeckillOrderTo orderTo) {
        // 保存订单信息
        OmsOrder orderEntity = new OmsOrder();
        orderEntity.setOrderSn(orderTo.getOrderSn());
        orderEntity.setMemberId(orderTo.getMemberId());
        orderEntity.setCreateTime(new Date());
        BigDecimal totalPrice = orderTo.getSeckillPrice().multiply(BigDecimal.valueOf(orderTo.getNum()));
        orderEntity.setPayAmount(totalPrice);
        orderEntity.setStatus(OrderStatusEnum.CREATE_NEW.getCode());

        //保存订单
        this.save(orderEntity);

        //保存订单项信息
        OmsOrderItem orderItem = new OmsOrderItem();
        orderItem.setOrderSn(orderTo.getOrderSn());
        orderItem.setRealAmount(totalPrice);

        orderItem.setSkuQuantity(orderTo.getNum());

        //保存商品的spu信息
        SpuInfoVo spuInofVo = orderProductFeignService.getSpuInfoBySkuId(orderTo.getSkuId());
        orderItem.setSpuId(spuInofVo.getId());
        orderItem.setSpuName(spuInofVo.getSpuName());
        orderItem.setSpuBrand(spuInofVo.getBrandName());
        orderItem.setCategoryId(spuInofVo.getCatalogId());
        //保存订单项数据
        orderItemService.save(orderItem);
    }

    @Override
    public IPage<OmsOrder> getOrderListMonthly(QueryVo<OmsOrder> queryVo) {
        HttpSession session = request.getSession();
        if(session != null){
            UmsMemberTo memberTo = (UmsMemberTo) session.getAttribute(AuthServerConstant.LOGIN_USER);
            if(memberTo==null){
                throw new RuntimeException("登录信息已经过期");
            }
            IPage<OmsOrder> page = this.getOmsOrderPage(queryVo);
            return page;
        }else{
            throw new RuntimeException("登录信息已经过期");
        }
    }

}
